package com.ruoyi.framework.web.service;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelReader;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.read.listener.ReadListener;
import com.alibaba.excel.read.metadata.ReadSheet;
import com.github.pagehelper.PageHelper;
import com.lx.information.domain.*;
import com.lx.information.domain.bo.*;
import com.lx.information.domain.vo.InformationCaseVO;
import com.lx.information.domain.vo.InformationJointCaseVO;
import com.lx.information.domain.vo.InformationVO;
import com.lx.information.service.*;
import com.ruoyi.common.config.RuoYiConfig;
import com.ruoyi.common.constant.HttpStatus;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.core.domain.bo.SysDictTypeBO;
import com.ruoyi.common.core.domain.entity.SysDept;
import com.ruoyi.common.core.domain.entity.SysDictData;
import com.ruoyi.common.core.domain.entity.SysDictType;
import com.ruoyi.common.core.domain.entity.SysUser;
import com.ruoyi.common.utils.FtpUtils;
import com.ruoyi.common.utils.SecurityUtils;
import com.ruoyi.common.utils.file.FileUploadUtils;
import com.ruoyi.common.utils.poi.ExcelUtil;
import com.ruoyi.framework.config.ServerConfig;
import com.ruoyi.system.mapper.SysUserMapper;
import com.ruoyi.system.service.ISysDeptService;
import com.ruoyi.system.service.ISysDictDataService;
import com.ruoyi.system.service.ISysDictTypeService;
import org.apache.tomcat.util.http.fileupload.FileItem;
import org.apache.tomcat.util.http.fileupload.disk.DiskFileItem;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;

/**
 * @author liuzhiqiang
 */
@Component
public class InformationService {
    private static final Logger log = LoggerFactory.getLogger(InformationService.class);
    @Autowired
    private ServerConfig serverConfig;
    @Autowired
    private ISysDictTypeService dictTypeService;
    @Autowired
    private ISysDictDataService dictDataService;
    @Autowired
    private SysUserMapper sysUserMapper;
    @Autowired
    private IInformationJointCaseService informationJointCaseService;
    @Autowired
    private ISysDeptService sysDeptService;
    @Autowired
    private IInformationImportRecordService informationImportRecordService;
    @Autowired
    private IInformationCaseService informationCaseService;
    @Autowired
    private IInformationCasePhoneService informationCasePhoneService;
    @Autowired
    private IInformationCaseAddressService informationCaseAddressService;

    public AjaxResult importExcel(MultipartFile file) {
        // 第一步 保存文件
        AjaxResult ajaxResult = saveFile(file);
        InformationImportRecord informationImportRecord = (InformationImportRecord) ajaxResult.get(AjaxResult.DATA_TAG);
        if (Objects.equals(ajaxResult.get(AjaxResult.CODE_TAG), HttpStatus.SUCCESS)) {
            // 第二部 文件转数据
            ajaxResult = fileToData(file);
            if (Objects.equals(ajaxResult.get(AjaxResult.CODE_TAG), HttpStatus.SUCCESS)) {
                List<ImportExcelData> excelDataList = (List<ImportExcelData>) ajaxResult.get(AjaxResult.DATA_TAG);
                // 第三步校验数据
                ajaxResult = verificationData(excelDataList, informationImportRecord.getId());
                if (Objects.equals(ajaxResult.get(AjaxResult.CODE_TAG), HttpStatus.SUCCESS)) {
                    // 第四步 保存数据
                    List<InformationJointCase> jointCases = (List<InformationJointCase>) ajaxResult.get(AjaxResult.DATA_TAG);
                    for (InformationJointCase jointCase : jointCases) {
                        informationJointCaseService.insertInformationJointCase(jointCase);
                    }
                    informationImportRecord.setExecutionStatus(IInformationImportRecordService.EXECUTION_STATUS_2);
                    informationImportRecordService.updateInformationImportRecord(informationImportRecord);
                    return AjaxResult.success();
                }
            }
        }
        informationImportRecord.setExecutionStatus(IInformationImportRecordService.EXECUTION_STATUS_3);
        informationImportRecord.setFailureReason((String) ajaxResult.get(AjaxResult.MSG_TAG));
        informationImportRecordService.updateInformationImportRecord(informationImportRecord);
        return ajaxResult;

    }


    private Map<String, SysDictTypeBO> getCustomerTypeMapKeyName() {
        // 查询所有客户
        SysDictType sysDictType = new SysDictType();
        sysDictType.setDictType("customer_");
        List<SysDictType> list = dictTypeService.selectDictTypeList(sysDictType);
        // list TO map
        Map<String, SysDictTypeBO> typeMap = new HashMap<>();
        for (SysDictType dictType : list) {
            SysDictTypeBO sysDictTypeBO = new SysDictTypeBO();
            BeanUtils.copyProperties(dictType, sysDictTypeBO);
            // 查询字典值
            SysDictData sysDictData = new SysDictData();
            sysDictData.setDictType(dictType.getDictType());
            List<SysDictData> dataList = dictDataService.selectDictDataList(sysDictData);
            Map<String, SysDictData> dataMap = new HashMap<>();
            for (SysDictData dictData : dataList) {
                dataMap.put(dictData.getDictLabel(), dictData);
            }
            sysDictTypeBO.setDataMap(dataMap);
            typeMap.put(dictType.getDictName(), sysDictTypeBO);
        }
        return typeMap;
    }

    private Map<String, SysUser> getUserMapKeyName(SysUser condition) {
        List<SysUser> users = sysUserMapper.selectUserList(condition);
        Map<String, SysUser> userMap = new HashMap<>();
        for (SysUser user : users) {
            userMap.put(user.getUserName(), user);
        }
        return userMap;
    }

    private Map<Long, SysUser> getUserMapKeyUserId() {
        List<SysUser> users = sysUserMapper.selectUserList(new SysUser());
        Map<Long, SysUser> userMap = new HashMap<>();
        for (SysUser user : users) {
            userMap.put(user.getUserId(), user);
        }
        return userMap;
    }

    /**
     * 校验数据
     *
     * @param excelDataList
     * @return
     */
    private AjaxResult verificationData(List<ImportExcelData> excelDataList, Long importId) {
        // 查询所有客户
        Map<String, SysDictTypeBO> typeMap = getCustomerTypeMapKeyName();
        // 获取用户所在的分公司
        SysDept sysDept = sysDeptService.recursiveParentUpGetBranchOffice(SecurityUtils.getLoginUser().getDeptId(), 0);
        // 本公司下用户
        SysUser condition = new SysUser();
        condition.setDeptId(sysDept.getDeptId());
        Map<String, SysUser> userMap = getUserMapKeyName(condition);
        // 异常消息
        List<String> msgList = new ArrayList<>();
        // 有效数据
        List<InformationJointCase> jointCases = new ArrayList<>();
        for (int i = 0; i < excelDataList.size(); i++) {
            ImportExcelData importExcelData = excelDataList.get(i);
            SysDictTypeBO sysDictTypeBO = typeMap.get(importExcelData.getCustomerName());
            if (sysDictTypeBO != null) {
                SysDictData sysDictData = sysDictTypeBO.getDataMap().get(importExcelData.getCustomerOrder());
                if (sysDictData != null) {
                    // 判断 用户是否是本公司用户
                    SysUser sysUser = userMap.get(importExcelData.getUserJob());
                    if (sysUser != null) {
                        if (CollectionUtil.isEmpty(msgList)) {
                            InformationJointCase informationJointCase = new InformationJointCase();
                            informationJointCase.setUserId(sysUser.getUserId());

                            informationJointCase.setCustomerName(importExcelData.getCustomerName());
                            informationJointCase.setCustomerOrder(importExcelData.getCustomerOrder());

                            informationJointCase.setCustomerNameDict(sysDictTypeBO.getDictType());
                            informationJointCase.setCustomerOrderDict(sysDictData.getDictValue());

                            informationJointCase.setDataState(IInformationJointCaseService.DATA_STATE_1);
                            informationJointCase.setExternalCode(importExcelData.getExternalCode());
                            informationJointCase.setFullName(importExcelData.getFullName());
                            informationJointCase.setIdNumber(importExcelData.getIdNumber());
                            informationJointCase.setJointCaseStartDate(importExcelData.getJointCaseStartDate());
                            informationJointCase.setJointCaseEndDate(importExcelData.getJointCaseEndDate());
                            informationJointCase.setRemarkOne(importExcelData.getRemarkOne());
                            informationJointCase.setRemarkTwo(importExcelData.getRemarkTwo());
                            informationJointCase.setRemarkThree(importExcelData.getRemarkThree());
                            informationJointCase.setBid(IdUtil.getSnowflakeNextId());
                            informationJointCase.setImportId(importId);
                            jointCases.add(informationJointCase);
                        }
                    } else {
                        msgList.add("第" + (i + 2) + "行用户在当前分公司下没有找到");
                    }
                } else {
                    msgList.add("第" + (i + 2) + "行客户手次没有找到");
                }
            } else {
                msgList.add("第" + (i + 2) + "行客户没有找到");
            }
        }
        if (CollectionUtil.isEmpty(msgList)) {
            return AjaxResult.success(jointCases);
        } else {
            return AjaxResult.error(String.join(",", msgList));
        }
    }

    /**
     * 文件转数据
     *
     * @param file
     * @return
     */
    private AjaxResult fileToData(MultipartFile file) {
        try {
            ExcelUtil<ImportExcelData> util = new ExcelUtil<>(ImportExcelData.class);
            List<ImportExcelData> excelDataList = util.importExcel(file.getInputStream());
            return AjaxResult.success(excelDataList);
        } catch (Exception e) {
            return AjaxResult.error("数据转换失败");
        }
    }

    /**
     * 保存文件
     *
     * @param file
     * @return
     */
    private AjaxResult saveFile(MultipartFile file) {
        InformationImportRecord informationImportRecord = new InformationImportRecord();
        informationImportRecord.setFileName(file.getOriginalFilename());
        informationImportRecord.setUploadBy(SecurityUtils.getLoginUser().getUserId());
        try {
            // 上传文件路径
            String filePath = RuoYiConfig.getUploadPath();
            // 上传并返回新文件名称
            String fileName;
            fileName = FileUploadUtils.upload(filePath, file);
            String url = serverConfig.getUrl() + fileName;
            informationImportRecord.setFileUrl(url);
            informationImportRecord.setExecutionStatus(IInformationImportRecordService.EXECUTION_STATUS_1);
            informationImportRecordService.insertInformationImportRecord(informationImportRecord);
            AjaxResult ajax = AjaxResult.success(informationImportRecord);
            return ajax;
        } catch (IOException e) {

            informationImportRecord.setExecutionStatus(IInformationImportRecordService.EXECUTION_STATUS_3);
            informationImportRecord.setFailureReason("文件保存失败");
            informationImportRecordService.insertInformationImportRecord(informationImportRecord);
            e.printStackTrace();
            AjaxResult ajax = AjaxResult.error("文件保存失败");
            ajax.put(AjaxResult.DATA_TAG, informationImportRecord);
            return ajax;
        }
    }

    public synchronized void informationUploadSftp() {
        // 所有用户
        Map<Long, SysUser> userMap = getUserMapKeyUserId();

        int i = 0;
        while (true) {
            InformationJointCase informationJointCase = new InformationJointCase();
            informationJointCase.setDataState(IInformationJointCaseService.DATA_STATE_1);
            PageHelper.startPage(i * 10000, 10000, "id").reasonable(true);
            List<InformationJointCase> list = informationJointCaseService.selectInformationJointCaseList(informationJointCase);
            List<ImportExcelDataTwo> dataTwoList = new ArrayList<>();
            List<Long> ids = new ArrayList<>();
            for (InformationJointCase jointCase : list) {
                // 用户工号
                if (userMap.get(jointCase.getUserId()) != null) {
                    ImportExcelDataTwo importExcelDataTwo = new ImportExcelDataTwo();
                    BeanUtils.copyProperties(jointCase, importExcelDataTwo, "bid");
                    importExcelDataTwo.setDataState("待查询");
                    importExcelDataTwo.setBid(String.valueOf(jointCase.getBid()));
                    importExcelDataTwo.setUserJob(userMap.get(jointCase.getUserId()).getUserName());
                    ids.add(jointCase.getId());
                    dataTwoList.add(importExcelDataTwo);
                }
            }
            if (CollectionUtil.isNotEmpty(dataTwoList)) {
                ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
                EasyExcel.write(byteArrayOutputStream, ImportExcelDataTwo.class)
                        .password(FtpUtils.ftpConfig.getSavePassword())
                        .sheet("模板")
                        .doWrite(() -> {
                            // 分页查询数据
                            return dataTwoList;
                        });
                ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(byteArrayOutputStream.toByteArray());
                String fileName = "informationUpload" + DateUtil.format(new Date(), "yyyyMMddHHmmss") + ".xlsx";
                Boolean on = FtpUtils.upload(byteArrayInputStream, fileName);
                if (on) {
                    informationJointCaseService.updateDataStateByIds(ids, IInformationJointCaseService.DATA_STATE_2);
                }
            }
            if (list.size() < 10000) {
                break;
            }
            i = i + 1;
        }


    }

    /**
     * 定时拉取
     */
    public synchronized void informationPullSftp() {
        // 1. 获取所有文件
        List<String> filePaths = FtpUtils.ls();
        for (String filePath : filePaths) {
            if (!StrUtil.startWith(filePath, "case_")) {
                continue;
            }
            // 2. 获取文件
            ByteArrayOutputStream byteArrayOutputStream = FtpUtils.get(filePath);
            if (byteArrayOutputStream != null) {
                // 3. 处理文件
                try (ExcelReader excelReader = EasyExcel.read(new ByteArrayInputStream(byteArrayOutputStream.toByteArray())).password(FtpUtils.ftpConfig.getReadPassword()).build()) {
                    // 这里为了简单 所以注册了 同样的head 和Listener 自己使用功能必须不同的Listener
                    ReadSheet caseSheet =
                            EasyExcel.readSheet("case").head(SftpCase.class).registerReadListener(new ReadListener<SftpCase>() {
                                @Override
                                public void invoke(SftpCase data, AnalysisContext context) {
                                    InformationCase informationCase = new InformationCase();
                                    BeanUtils.copyProperties(data, informationCase, "bid");
                                    informationCase.setBid(Long.valueOf(data.getBid()));
                                    informationCaseService.insertInformationCase(informationCase);
                                    // 处理数据
                                    InformationJointCase informationJointCase = informationJointCaseService.selectInformationJointCaseByBId(informationCase.getBid());
                                    if (informationCase != null) {
                                        if (!StrUtil.equals(informationJointCase.getDataState(), IInformationJointCaseService.DATA_STATE_3)) {
                                            if (StrUtil.equals(informationCase.getDataState(), "查询成功")) {
                                                informationJointCase.setDataState(IInformationJointCaseService.DATA_STATE_4);
                                            } else {
                                                informationJointCase.setDataState(IInformationJointCaseService.DATA_STATE_3);
                                            }
                                        }
                                        informationJointCase.setJointCaseIdNumber(informationCase.getIdNo());
                                        informationJointCase.setJointCaseNumber(informationJointCase.getJointCaseNumber() + 1);
                                        if (informationCase.getCaseAmount() != null) {
                                            informationJointCase.setJointCaseAmount(informationJointCase.getJointCaseAmount().add(new BigDecimal(informationCase.getCaseAmount())));
                                        }
                                        if (informationCase.getRepayAllMoneyYes() != null) {
                                            informationJointCase.setRecoveryAmount(informationJointCase.getRecoveryAmount().add(new BigDecimal(informationCase.getRepayAllMoneyYes())));
                                        }
                                        if (informationJointCase.getLatestRepaymentDate() == null || informationCase.getLatestRepaymentDate().getTime() > informationJointCase.getLatestRepaymentDate().getTime()) {
                                            informationJointCase.setLatestRepaymentDate(informationCase.getLatestRepaymentDate());
                                            informationJointCase.setLatestRepaymentAmount(new BigDecimal(informationCase.getLatestRepaymentAmount()));
                                        }
                                        informationJointCaseService.updateInformationJointCase(informationJointCase);
                                    }
                                }

                                @Override
                                public void doAfterAllAnalysed(AnalysisContext context) {
                                    log.info("数据处理完");
                                }
                            }).build();

                    ReadSheet phoneSheet =
                            EasyExcel.readSheet("phone").head(SftpPhone.class).registerReadListener(new ReadListener<SftpPhone>() {
                                @Override
                                public void invoke(SftpPhone data, AnalysisContext context) {
                                    InformationCasePhone informationCasePhone = new InformationCasePhone();
                                    BeanUtils.copyProperties(data, informationCasePhone, "bid");
                                    informationCasePhone.setBid(Long.valueOf(data.getBid()));
                                    InformationCase informationCase = informationCaseService.selectInformationCaseByBidAndCaseNo(informationCasePhone.getBid(), informationCasePhone.getCaseNo());
                                    if (informationCase != null) {
                                        informationCasePhone.setCaseId(informationCase.getId());
                                        informationCasePhoneService.insertInformationCasePhone(informationCasePhone);
                                    }
                                }

                                @Override
                                public void doAfterAllAnalysed(AnalysisContext context) {
                                    log.info("数据处理完");
                                }
                            }).build();
                    ReadSheet addressSheet =
                            EasyExcel.readSheet("address").head(SftpAddress.class).registerReadListener(new ReadListener<SftpAddress>() {
                                @Override
                                public void invoke(SftpAddress data, AnalysisContext context) {
                                    InformationCaseAddress informationCaseAddress = new InformationCaseAddress();
                                    BeanUtils.copyProperties(data, informationCaseAddress, "bid");
                                    informationCaseAddress.setBid(Long.valueOf(data.getBid()));
                                    InformationCase informationCase = informationCaseService.selectInformationCaseByBidAndCaseNo(informationCaseAddress.getBid(), informationCaseAddress.getCaseNo());
                                    if (informationCase != null) {
                                        informationCaseAddress.setCaseId(informationCase.getId());
                                        informationCaseAddressService.insertInformationCaseAddress(informationCaseAddress);
                                    }
                                }

                                @Override
                                public void doAfterAllAnalysed(AnalysisContext context) {
                                    log.info("数据处理完");
                                }
                            }).build();
                    excelReader.read(caseSheet, phoneSheet, addressSheet);
                    try {
                        // 保存文件
                        String file = FileUploadUtils.saveFile(byteArrayOutputStream.toByteArray(), filePath);
                        log.info("处理文件:{},文件存储位置:{}", filePath, file);
                    } catch (Exception e) {
                        log.info("文件保存失败: {}", e.getMessage());
                    }

                    // 读完删除文件
                    FtpUtils.rm(filePath);
                }
            }
        }
    }

    public InformationVO info(Long id) {
        InformationJointCase informationJointCase = informationJointCaseService.selectInformationJointCaseById(id);
        InformationJointCaseVO informationJointCaseVO = new InformationJointCaseVO();
        BeanUtils.copyProperties(informationJointCase, informationJointCaseVO);
        // 查询案件
        InformationCase informationCase = new InformationCase();
        informationCase.setBid(informationJointCase.getBid());
        List<InformationCase> informationCaseList = informationCaseService.selectInformationCaseList(informationCase);
        List<InformationCaseVO> caseVOList = new ArrayList<>();
        for (InformationCase aCase : informationCaseList) {
            InformationCaseVO informationCaseVO = new InformationCaseVO();
            BeanUtils.copyProperties(aCase, informationCaseVO);
            // 查询电话
            InformationCasePhone informationCasePhone = new InformationCasePhone();
            informationCasePhone.setCaseId(aCase.getId());
            List<InformationCasePhone> phoneList = informationCasePhoneService.selectInformationCasePhoneList(informationCasePhone);
            informationCaseVO.setPhoneList(phoneList);
            // 查询地址
            InformationCaseAddress informationCaseAddress = new InformationCaseAddress();
            informationCaseAddress.setCaseId(aCase.getId());
            List<InformationCaseAddress> addressList = informationCaseAddressService.selectInformationCaseAddressList(informationCaseAddress);
            informationCaseVO.setAddressList(addressList);
            caseVOList.add(informationCaseVO);
        }
        InformationVO informationVO = new InformationVO();
        informationVO.setInformationJointCaseVO(informationJointCaseVO);
        informationVO.setCaseVOList(caseVOList);
        return informationVO;
    }
}
